package com.qzsoft.zhjd.monitoring.modules.videomonitor.service.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qzsoft.zhjd.common.components.BaseServiceComponent;
import com.qzsoft.zhjd.common.enums.BizCode;
import com.qzsoft.zhjd.common.utils.RenExceptionUtils;
import com.qzsoft.zhjd.monitoring.config.ZLMServerConfig;
import com.qzsoft.zhjd.monitoring.modules.videomonitor.dto.StreamInfoDto;
import com.qzsoft.zhjd.monitoring.modules.videomonitor.entity.VideoMonitorEntity;
import com.qzsoft.zhjd.monitoring.modules.videomonitor.mapper.VideoMonitorMapper;
import com.qzsoft.zhjd.monitoring.modules.videomonitor.service.VideoMonitorService;
import com.qzsoft.zhjd.monitoring.modules.zlm.manager.ZLMServerManager;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName VideoMonitorServiceImpl
 * @Description 视频监控业务接口实现
 * @author linhuawei
 * @since 2022-03-22
 */
@Slf4j
@Service
public class VideoMonitorServiceImpl extends ServiceImpl<VideoMonitorMapper, VideoMonitorEntity>
        implements VideoMonitorService {

//    @Autowired
//    private ZLMRestfulUtils zlmRestfulUtils;

    @Autowired
    private ZLMServerManager zlmServerManager;

    @Autowired
    private BaseServiceComponent baseServiceComponent;

//    @Override
//    public IPage<VideoMonitorListDto> pageDto(Map<String, Object> params) {
//        IPage<VideoMonitorListDto> page = baseServiceComponent.getPage(params, VideoMonitorListDto.class);
//        return baseMapper.queryDto(page, params);
//    }

    @Override
    public IPage<VideoMonitorEntity> page(Map<String, Object> params) {
        IPage<VideoMonitorEntity> page = baseServiceComponent.getPage(params, VideoMonitorEntity.class);
        QueryWrapper<VideoMonitorEntity> queryWrapper = new QueryWrapper<VideoMonitorEntity>();
        if (ObjectUtils.isNotEmpty(params.get("id"))) {
            queryWrapper.eq("id", params.get("id").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("baseCode"))) {
            queryWrapper.eq("base_code", params.get("baseCode").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("groupCode"))) {
            queryWrapper.eq("group_code", params.get("groupCode").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("groupPath"))) {
            queryWrapper.likeRight("group_code", params.get("groupPath").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("resourceId"))) {
            queryWrapper.eq("resource_id", params.get("resourceId").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("resourceType"))) {
            queryWrapper.eq("resource_type", params.get("resourceType").toString());
        }
        queryWrapper.orderByAsc("base_code,name");
        return baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public List<VideoMonitorEntity> list(Map<String, Object> params) {
        QueryWrapper<VideoMonitorEntity> queryWrapper = new QueryWrapper<VideoMonitorEntity>();
        if (ObjectUtils.isNotEmpty(params.get("baseCode"))) {
            queryWrapper.eq("base_code", params.get("baseCode").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("resourceId"))) {
            queryWrapper.eq("resource_id", params.get("resourceId").toString());
        }
        if (ObjectUtils.isNotEmpty(params.get("resourceType"))) {
            queryWrapper.eq("resource_type", params.get("resourceType").toString());
        }
        return baseMapper.selectList(queryWrapper);
    }

//    @Override
//    public List<VideoMonitorEntity> listAllEnable() {
//        QueryWrapper<VideoMonitorEntity> queryWrapper = new QueryWrapper<VideoMonitorEntity>();
//        queryWrapper.eq("enable", 1);
//        return baseMapper.selectList(queryWrapper);
//    }

    @Override
    public StreamInfoDto getStreamInfo(String app, String stream, String resourceType) {
        // 判断视频监控是否重复
        QueryWrapper<VideoMonitorEntity> queryWrapper = new QueryWrapper<VideoMonitorEntity>();
        queryWrapper.eq("app", app);
        queryWrapper.eq("stream", stream);
        if (ObjectUtils.isNotEmpty(resourceType)) {
            queryWrapper.eq("resource_type", resourceType);
        }
        queryWrapper.last(" LIMIT 0,1 ");
        VideoMonitorEntity entity = baseMapper.selectOne(queryWrapper);
        if (null == entity) {
            log.info("视频监控[app=" + app + ",stream=" + stream + "]不存在");
            return null;
        }

//        // 获取播放信息
//        StreamInfoDto dto = null;
//        JSONArray array = zlmRestfulUtils.getMediaList(app, stream);
//        if (null == array) {
//            if (zlmRestfulUtils.addStreamProxy(entity)) {
//                dto = coverStreamInfoDto(app, stream);
//                log.info("视频监控[app=" + app + ",stream=" + stream + "]流代理不存在,添加成功");
//            } else {
//                log.info("视频监控[app=" + app + ",stream=" + stream + "]流代理不存在,添加失败");
//            }
//        } else {
//            log.info("视频监控[app=" + app + ",stream=" + stream + "]流代理存在");
//            dto = coverStreamInfoDto(app, stream);
//        }
//
//        // 更新状态
//        if (null == dto) {
//            if (1 == entity.getEnable()) {
//                UpdateWrapper<VideoMonitorEntity> updateWrapper = new UpdateWrapper<VideoMonitorEntity>();
//                updateWrapper.eq("id", entity.getId());
//                updateWrapper.set("enable", 0);
//                baseMapper.update(null, updateWrapper);
//            }
//        } else {
//            if (0 == entity.getEnable()) {
//                UpdateWrapper<VideoMonitorEntity> updateWrapper = new UpdateWrapper<VideoMonitorEntity>();
//                updateWrapper.eq("id", entity.getId());
//                updateWrapper.set("enable", 1);
//                baseMapper.update(null, updateWrapper);
//            }
//        }

        StreamInfoDto dto = coverStreamInfoDto(app, stream);
        return dto;
    }

    @Override
    public boolean save(VideoMonitorEntity entity) {
        // 判断视频监控是否重复
        QueryWrapper<VideoMonitorEntity> queryWrapper = new QueryWrapper<VideoMonitorEntity>();
        queryWrapper.eq("app", entity.getApp());
        queryWrapper.eq("stream", entity.getStream());
        Integer count = baseMapper.selectCount(queryWrapper);
        if (null != count && 0 < count) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR,
                    "视频监控[app=" + entity.getApp() + ",stream=" + entity.getStream() + "]已经存在");
        }

        // 添加视频监控
        entity.setType("default");
        entity.setEnable(1);
        entity.setEnableHls(0);
        entity.setEnableMp4(0);
        super.save(entity);

        // TODO 添加推流代理

        return true;
    }

//    @Override
//    public void disable(String id) {
//        UpdateWrapper<VideoMonitorEntity> updateWrapper = new UpdateWrapper<VideoMonitorEntity>();
//        updateWrapper.eq("id", id);
//        updateWrapper.set("enable", 0);
//        baseMapper.update(null, updateWrapper);
//    }
//
//    @Override
//    public void disable(String app, String stream) {
//        UpdateWrapper<VideoMonitorEntity> updateWrapper = new UpdateWrapper<VideoMonitorEntity>();
//        updateWrapper.eq("app", app);
//        updateWrapper.eq("stream", stream);
//        updateWrapper.set("enable", 0);
//        baseMapper.update(null, updateWrapper);
//    }

    @Override
    public boolean removeById(Serializable id) {
        // 判断视频监控是否存在
        VideoMonitorEntity entity = baseMapper.selectById(id);
        if (null == entity) {
            return true;
        }

        // 删除视频监控
        super.removeById(id);

        // TODO 关闭推流代理

        return true;
    }

    @Override
    public VideoMonitorEntity getByAppAndStream(String app, String stream) {
        QueryWrapper<VideoMonitorEntity> queryWrapper = new QueryWrapper<VideoMonitorEntity>();
        queryWrapper.eq("app", app);
        queryWrapper.eq("stream", stream);
        queryWrapper.last(" LIMIT 0,1 ");
        return baseMapper.selectOne(queryWrapper);
    }

    /**
     * @Title coverStreamInfoDto
     * @Description 转化播放对象
     * @param app
     * @param stream
     * @return
     */
    private StreamInfoDto coverStreamInfoDto(String app, String stream) {
        // 获取缓存的zlm配置,如果配置不存在,返回空值
        ZLMServerConfig config = zlmServerManager.getCacheServerConfig();
        if (null == config) {
            return null;
        }

        // 拼接播放对象
        String wanIp = config.getWanIp();
        String httpPort = config.getHttpPort();
//        String rtmpPort = config.getRtmpPort();
//        String rtspPort = config.getRtspPort();
        StreamInfoDto dto = new StreamInfoDto();
        dto.setApp(app);
        dto.setStream(stream);
//        dto.setRtmp(String.format("rtmp://%s:%s/%s/%s", wanIp, rtmpPort, app, stream));
//        dto.setRtsp(String.format("rtsp://%s:%s/%s/%s", wanIp, rtspPort, app, stream));
        dto.setFlv(String.format("http://%s:%s/%s/%s.flv", wanIp, httpPort, app, stream));
        dto.setWsFlv(String.format("ws://%s:%s/%s/%s.flv", wanIp, httpPort, app, stream));
        dto.setHls(String.format("http://%s:%s/%s/%s/hls.m3u8", wanIp, httpPort, app, stream));
        dto.setWsHls(String.format("ws://%s:%s/%s/%s/hls.m3u8", wanIp, httpPort, app, stream));
        dto.setFmp4(String.format("http://%s:%s/%s/%s.live.mp4", wanIp, httpPort, app, stream));
        dto.setWsFmp4(String.format("ws://%s:%s/%s/%s.live.mp4", wanIp, httpPort, app, stream));
        dto.setTs(String.format("http://%s:%s/%s/%s.live.ts", wanIp, httpPort, app, stream));
        dto.setWsTs(String.format("ws://%s:%s/%s/%s.live.ts", wanIp, httpPort, app, stream));
//        dto.setRtc(String.format("http://%s:%s/index/api/webrtc?app=%s&stream=%s&type=play", wanIp, httpPort, app, stream));
        return dto;
    }

}
